import sys
import json
import requests
from urllib.parse import quote
from typing import List, Dict, Union
from collections import defaultdict


class DictionaryAPI:
    """可重用的字典查询组件"""
    
    def __init__(self, timeout=10):
        self.timeout = timeout
        self.headers = {
            "User-Agent": "PythonDictClient/2.0",
            "Accept": "application/json"
        }
    
    def query(self, word: str) -> Union[List[Dict], str]:
        """主查询方法，返回原始数据或错误信息"""
        try:
            response = requests.get(
                f"https://api.dictionaryapi.dev/api/v2/entries/en/{quote(word)}",
                headers=self.headers,
                timeout=self.timeout
            )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.HTTPError as e:
            if response.status_code == 404:
                return f"Error: Word '{word}' not found"
            return f"API Error: {str(e)}"
        except requests.exceptions.RequestException as e:
            return f"Network Error: {str(e)}"
        except json.JSONDecodeError:
            return "Error: Invalid API response"

    def format_result(self, data: Union[List[Dict], str], color=False) -> str:
        """改进后的格式化方法"""
        if isinstance(data, str):
            return data
        
        output = []
        color_codes = self._get_color_codes(color)
        
        # 按单词分组合并条目
        grouped_entries = defaultdict(list)
        for entry in data:
            grouped_entries[entry['word'].lower()].append(entry)
        
        for word, entries in grouped_entries.items():
            # 合并基本信息
            main_word = entries[0]['word'].capitalize()
            output.append(f"{color_codes['header']}Word:{color_codes['reset']} {main_word}")
            
            # 合并音标
            all_phonetics = []
            for entry in entries:
                all_phonetics.extend(entry['phonetics'])
            phonetics = list({p['text'] for p in all_phonetics if p.get('text')})
            if phonetics:
                output.append(f"{color_codes['header']}Phonetics:{color_codes['reset']} {', '.join(phonetics)}")
            
            # 合并发音链接
            audio_links = list({p['audio'] for p in all_phonetics if p['audio']})
            if audio_links:
                output.append(f"\n{color_codes['header']}Pronunciations:{color_codes['reset']}")
                output.extend([f"- {link}" for link in audio_links])
            
            # 合并所有词性
            all_meanings = []
            for entry in entries:
                all_meanings.extend(entry['meanings'])
            
            # 按词性分组
            meaning_groups = defaultdict(list)
            for meaning in all_meanings:
                meaning_groups[meaning['partOfSpeech']].append(meaning)
            
            output.append(f"\n{color_codes['header']}Meanings:{color_codes['reset']}")
            for pos, meanings in meaning_groups.items():
                pos_header = pos.capitalize()
                output.append(f"\n{color_codes['subheader']}{pos_header}:{color_codes['reset']}")
                
                definition_counter = 1
                for meaning in meanings:
                    for definition in meaning['definitions']:
                        output.append(f"  {definition_counter}. {definition['definition']}")
                        if definition.get('example'):
                            ex = f"{color_codes['example']}Example:{color_codes['reset']} {definition['example']}"
                            output.append(f"     {ex}")
                        definition_counter += 1
                    
                    if meaning.get('synonyms'):
                        syns = ', '.join(meaning['synonyms'])
                        output.append(f"  {color_codes['synonyms']}Synonyms:{color_codes['reset']} {syns}")
                    if meaning.get('antonyms'):
                        ants = ', '.join(meaning['antonyms'])
                        output.append(f"  {color_codes['antonyms']}Antonyms:{color_codes['reset']} {ants}")
            
            # 合并来源
            all_sources = list({url for entry in entries for url in entry['sourceUrls']})
            output.append(f"\n{color_codes['header']}Sources:{color_codes['reset']}")
            output.extend([f"- {url}" for url in all_sources])
        
        return '\n'.join(output)
    
    def _get_color_codes(self, color_enabled):
        return {
            "header": "\033[1m" if color_enabled else "",
            "subheader": "\033[1;36m" if color_enabled else "",  # 青色
            "example": "\033[3m" if color_enabled else "",
            "synonyms": "\033[32m" if color_enabled else "",
            "antonyms": "\033[31m" if color_enabled else "",
            "reset": "\033[0m" if color_enabled else ""
        }

def main():
    """命令行入口"""
    import argparse
    
    parser = argparse.ArgumentParser(description='Dictionary CLI Tool')
    parser.add_argument('word', nargs='?', help='Word to look up')
    parser.add_argument('--color', action='store_true', help='Enable color output')
    args = parser.parse_args()
    
    word = args.word or input("Enter a word to lookup: ").strip()
    if not word:
        sys.exit("Error: No word specified")
    
    api = DictionaryAPI()
    result = api.query(word)
    print(api.format_result(result, color=args.color))

if __name__ == "__main__":
    main()